package nl.rug.ml.dobbelen.game;

import java.util.ArrayList;
import java.util.List;

import nl.rug.ml.dobbelen.agent.DobbelenAgent;
import nl.rug.ml.dobbelen.agent.DobbelenHumanPlayer;
import nl.rug.ml.dobbelen.learning.DobbelenLearningAgent;

/**
 * A simple game for both humans and agents.
 * 
 * @author Do Bich Ngoc (bichngocdo89@gmail.com)
 * 
 */
public class InteractiveDobbelenGame {

	private List<DobbelenAgent> players;

	public InteractiveDobbelenGame(int numDice, int numHumanPlayer, int numAutoPlayer) {
		players = new ArrayList<DobbelenAgent>(numHumanPlayer + numAutoPlayer);
		for (int i = 0; i < numHumanPlayer; i++) {
			players.add(new DobbelenHumanPlayer(numDice));
		}
		for (int i = 0; i < numAutoPlayer; i++) {
			players.add(new DobbelenLearningAgent(numDice));
		}
	}

	public void play() {
		int rowNo = 0;
		System.out.println("Start game");
		do {
			rowNo++;
			int playerNo = 0;
			for (DobbelenAgent player : players) {
				System.out.printf("Row %d - Player % d\n", rowNo, ++playerNo);
				player.throwDices();

				for (;;) {
					if (DobbelenCondition.mustReThrow(player.getDices()) && !player.willReThrow()) {
						System.out.println("You must re-throw.");
						continue;
					}
					if (player.willReThrow()) {
						List<Dice> heldDices = player.chooseDicesToHold();
						if (DobbelenCondition.mustThrowAll(player.getDices()) && !heldDices.isEmpty()) {
							System.out.println("You must re-throw all dices.");
							continue;
						}
						player.reThrowDices(heldDices);
					}
					else {
						player.updateScore();
						break;
					}
				}

				if (player.getTotalScore() > 10000) {
					System.out.println("Player " + playerNo + " won!");
					return;
				}
			}
			System.out.println();
		}
		while (true);
	}

	public static void main(String[] args) {
		InteractiveDobbelenGame game = new InteractiveDobbelenGame(6, 0, 2);
		game.play();
	}

}
